package com.heima.article.service.impl;

import com.alibaba.dashscope.aigc.conversation.Conversation;
import com.alibaba.dashscope.aigc.conversation.ConversationParam;
import com.alibaba.dashscope.aigc.conversation.ConversationResult;
import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.aigc.generation.models.QwenParam;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.MessageManager;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.heima.article.service.AIChatService;
import com.heima.article.service.ApArticleService;
import com.heima.article.service.ArticleClassifyService;
import com.heima.article.service.ArticleScoreService;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.article.dtos.ChatDto;
import com.heima.model.article.dtos.OneChatDto;
import com.heima.model.article.dtos.ScoreDto;
import com.heima.model.common.dtos.ResponseResult;
import com.alibaba.dashscope.utils.Constants;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.utils.thread.AppThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

/**
 * @ClassName AIChatServiceImpl
 * @Description TODO
 * @Author Neo
 * @Date 2024/3/6 13:31
 * @Version 1.0
 */
@Service
@Slf4j
public class AIChatServiceImpl implements AIChatService {
    @Autowired
    private ApArticleService apArticleService;
    @Autowired
    private ArticleScoreService articleScoreService;
    @Autowired
    private ArticleClassifyService articleClassifyService;
    static {
        Constants.apiKey="sk-ce3f1f7a62f64900a502f19182d0d56b";
    }
    @Override
    public ResponseResult<String> chat(String question) {
        try {
            return ResponseResult.okResult(quickStart(question));
        } catch (ApiException | NoApiKeyException | InputRequiredException e) {
            System.out.println(e.getMessage());
        }
        return ResponseResult.errorResult(null);
    }

    @Override
    public ResponseResult<String> chat2(String question) {
        try {
            return ResponseResult.okResult(quickStart2(question));
        } catch (ApiException | NoApiKeyException | InputRequiredException e) {
            System.out.println(e.getMessage());
        }
        return ResponseResult.errorResult(null);
    }

    @Override
    public ResponseResult<String> chatWithMessage(ChatDto chatDto)  {
        try {
            if (chatDto==null|| CollectionUtils.isEmpty(chatDto.getChatDtoList())){
                return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
            }
            Generation gen = new Generation();
            MessageManager msgManager = new MessageManager(chatDto.getChatDtoList().size()+1);
            Message systemMsg = Message.builder().role(Role.SYSTEM.getValue()).content("You are a helpful assistant.").build();
            msgManager.add(systemMsg);
            for (OneChatDto oneChatDto : chatDto.getChatDtoList()) {
                Message msg=new Message();
                if(oneChatDto.getRole()==null||(oneChatDto.getRole().equals("user")&&oneChatDto.getRole().equals("assistant"))){
                    return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
                }
                if(StringUtils.equals(oneChatDto.getRole(),"user")){
                    msg = Message.builder().role(Role.USER.getValue()).content(oneChatDto.getContent()).build();
                }else{
                    msg = Message.builder().role(Role.ASSISTANT.getValue()).content(oneChatDto.getContent()).build();
                }
                msgManager.add(msg);
            }
            Message message = msgManager.get().get(chatDto.getChatDtoList().size());
            if(!message.getRole().equals(Role.USER.getValue())){
                return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
            }
            String content = message.getContent();
            content = content + "。请注意，如果提问的内容不是计算机学习相关的，请你回复：请不要提问和计算机学习无关的话题";
            //多轮对话内容可存入数据库，加载时循环放入放入MessageManager 对象实现对话内容加载
            message.setContent(content);
            QwenParam params = QwenParam.builder().model(Conversation.Models.QWEN_MAX)//此处可根据自己需要更换AI模型
                    .messages(msgManager.get())
                    .seed(1234)
                    .topP(0.8)
                    .resultFormat("message")
                    .enableSearch(false)
                    .maxTokens(1500)
                    .temperature((float)1.0)
                    .repetitionPenalty((float)1.0)
                    .build();


            GenerationResult result = gen.call(params);
            String text = result.getOutput().getChoices().get(0).getMessage().getContent();
            return ResponseResult.okResult(text);
        } catch (NoApiKeyException e) {
            throw new RuntimeException(e);
        } catch (InputRequiredException e) {
            throw new RuntimeException(e);
        }
    }


    public String quickStart(String prompt) throws ApiException, NoApiKeyException, InputRequiredException {
        ConversationResult result=null;
        try {
            Conversation conversation = new Conversation();
            ConversationParam param = ConversationParam
                    .builder()
                    .model(Conversation.Models.QWEN_TURBO)
                    .prompt(prompt)
                    .build();
             result = conversation.call(param);

            return result.getOutput().getText();
        } finally {
            ArticleDto articleDto = new ArticleDto();
            ScoreDto scoreDto = new ScoreDto();
            ApUser user = AppThreadLocalUtil.getUser();
            if(!articleClassifyService.classifyArticle(null,result.getOutput().getText()).contains("其他")){
                if(user!=null&&user.getId()!=null){
                    articleDto.setAuthorId(Long.valueOf(user.getId()));
                    scoreDto.setUserId(Long.valueOf(user.getId()));
                }else{
                    articleDto.setAuthorId(1L);
                    scoreDto.setUserId(1L);
                }
                articleDto.setTitle(prompt);
                articleDto.setContent(result.getOutput().getText());

                ResponseResult<Long> responseResult = apArticleService.saveArticle(articleDto);

                scoreDto.setScore(5);
                scoreDto.setArticleId(responseResult.getData());
                articleScoreService.Score(scoreDto);
            }

        }
    }
    public String quickStart2(String prompt) throws ApiException, NoApiKeyException, InputRequiredException {
        ConversationResult result=null;

            Conversation conversation = new Conversation();
            ConversationParam param = ConversationParam
                    .builder()
                    .model(Conversation.Models.QWEN_TURBO)
                    .prompt(prompt)
                    .build();
            result = conversation.call(param);

            return result.getOutput().getText();

    }
}
